package gr.handmademarket.util;

import gr.handmademarket.po.paypal.CheckoutResponse;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import javax.xml.parsers.ParserConfigurationException;

import org.xml.sax.SAXException;

import urn.ebay.api.PayPalAPI.DoExpressCheckoutPaymentReq;
import urn.ebay.api.PayPalAPI.DoExpressCheckoutPaymentRequestType;
import urn.ebay.api.PayPalAPI.DoExpressCheckoutPaymentResponseType;
import urn.ebay.api.PayPalAPI.GetExpressCheckoutDetailsReq;
import urn.ebay.api.PayPalAPI.GetExpressCheckoutDetailsRequestType;
import urn.ebay.api.PayPalAPI.GetExpressCheckoutDetailsResponseType;
import urn.ebay.api.PayPalAPI.PayPalAPIInterfaceServiceService;
import urn.ebay.api.PayPalAPI.SetExpressCheckoutReq;
import urn.ebay.api.PayPalAPI.SetExpressCheckoutRequestType;
import urn.ebay.api.PayPalAPI.SetExpressCheckoutResponseType;
import urn.ebay.apis.CoreComponentTypes.BasicAmountType;
import urn.ebay.apis.eBLBaseComponents.DoExpressCheckoutPaymentRequestDetailsType;
import urn.ebay.apis.eBLBaseComponents.ErrorType;
import urn.ebay.apis.eBLBaseComponents.GetExpressCheckoutDetailsResponseDetailsType;
import urn.ebay.apis.eBLBaseComponents.PayerInfoType;
import urn.ebay.apis.eBLBaseComponents.PaymentActionCodeType;
import urn.ebay.apis.eBLBaseComponents.PaymentDetailsType;
import urn.ebay.apis.eBLBaseComponents.SetExpressCheckoutRequestDetailsType;

import com.paypal.exception.ClientActionRequiredException;
import com.paypal.exception.HttpErrorException;
import com.paypal.exception.InvalidCredentialException;
import com.paypal.exception.InvalidResponseDataException;
import com.paypal.exception.MissingCredentialException;
import com.paypal.exception.SSLConfigurationException;
import com.paypal.sdk.exceptions.OAuthException;

public class PaymentUtils {

	static final String RETURN_URL = "http://localhost:8080/WebHandMadeMarket/checkout";
	
	static final String CANCEL_URL = "http://localhost:8080/WebHandMadeMarket/home";
	
	public String callSetExpressCheckout(double amount){
		try {
			PayPalAPIInterfaceServiceService service = new PayPalAPIInterfaceServiceService(this
					.getClass().getResourceAsStream("/gr/handmademarket/resources/sdk_config.properties"));
			SetExpressCheckoutRequestType setExpressCheckoutReqType = new SetExpressCheckoutRequestType();
			SetExpressCheckoutRequestDetailsType details = new SetExpressCheckoutRequestDetailsType();
			details.setReturnURL(RETURN_URL);
			details.setCancelURL(CANCEL_URL);
			BasicAmountType amountType = createAmountType(amount);
			details.setOrderTotal(amountType);
			details.setPaymentDetails(createPaymentDetails(amountType));
			setExpressCheckoutReqType.setSetExpressCheckoutRequestDetails(details);
			SetExpressCheckoutReq expressCheckoutReq = new SetExpressCheckoutReq();
			expressCheckoutReq.setSetExpressCheckoutRequest(setExpressCheckoutReqType);
			SetExpressCheckoutResponseType setExpressCheckoutResponse = service.setExpressCheckout(expressCheckoutReq);
			if (setExpressCheckoutResponse != null) {
				if (setExpressCheckoutResponse.getAck().toString()
						.equalsIgnoreCase("SUCCESS")) {
					String token = setExpressCheckoutResponse.getToken();
					return token; 
				} else {
					List<ErrorType> errorTypes = setExpressCheckoutResponse.getErrors();
					for (ErrorType errorType : errorTypes){
						System.out.println("code: " + errorType.getErrorCode() + " message: " + errorType.getLongMessage());
					}
				}
			}
			
		} catch (IOException e) {
			throw new RuntimeException(e);
		} catch (SSLConfigurationException e) {
			throw new RuntimeException(e);
		} catch (InvalidCredentialException e) {
			throw new RuntimeException(e);
		} catch (HttpErrorException e) {
			throw new RuntimeException(e);
		} catch (InvalidResponseDataException e) {
			throw new RuntimeException(e);
		} catch (ClientActionRequiredException e) {
			throw new RuntimeException(e);
		} catch (MissingCredentialException e) {
			throw new RuntimeException(e);
		} catch (OAuthException e) {
			throw new RuntimeException(e);
		} catch (InterruptedException e) {
			throw new RuntimeException(e);
		} catch (ParserConfigurationException e) {
			throw new RuntimeException(e);
		} catch (SAXException e) {
			throw new RuntimeException(e);
		}
		return null;
	}
	
	private List<PaymentDetailsType> createPaymentDetails(BasicAmountType amountType){
		List<PaymentDetailsType> pdts = new ArrayList<PaymentDetailsType>();
		PaymentDetailsType pdt = new PaymentDetailsType();
		pdt.setPaymentAction(PaymentActionCodeType.SALE);
		pdt.setItemTotal(amountType);
		pdts.add(pdt);
		return pdts;
	}
	
	private List<PaymentDetailsType> getPaymentDetails(BasicAmountType amountType){
		List<PaymentDetailsType> payDetailType = new ArrayList<PaymentDetailsType>();
		PaymentDetailsType paymentDetails = new PaymentDetailsType();
		paymentDetails.setOrderTotal(amountType);
		payDetailType.add(paymentDetails);
		paymentDetails.setPaymentAction(PaymentActionCodeType.SALE);
		return payDetailType;
	}
	
	private BasicAmountType createAmountType(double amount){
		BasicAmountType amountType = new BasicAmountType();
		amountType.setValue(Double.toString(amount));
		return amountType;
	}

	public CheckoutResponse callGetExpressCheckout(String token){
		try {
			PayPalAPIInterfaceServiceService service = new PayPalAPIInterfaceServiceService(this
					.getClass().getResourceAsStream("/gr/handmademarket/resources/sdk_config.properties"));
			GetExpressCheckoutDetailsReq req = new GetExpressCheckoutDetailsReq();
			GetExpressCheckoutDetailsRequestType reqType = new GetExpressCheckoutDetailsRequestType(token);
			req.setGetExpressCheckoutDetailsRequest(reqType);
			GetExpressCheckoutDetailsResponseType resp = service.getExpressCheckoutDetails(req);
			GetExpressCheckoutDetailsResponseDetailsType responseDetails = resp.getGetExpressCheckoutDetailsResponseDetails();
			PayerInfoType payerInfo = responseDetails.getPayerInfo();
			CheckoutResponse response = new CheckoutResponse();
			response.setAddress(payerInfo.getAddress());
			response.setPayer(payerInfo.getPayerID());
			return response;
		} catch (IOException e) {
			throw new RuntimeException(e);
		} catch (SSLConfigurationException e) {
			throw new RuntimeException(e);
		} catch (InvalidCredentialException e) {
			throw new RuntimeException(e);
		} catch (HttpErrorException e) {
			throw new RuntimeException(e);
		} catch (InvalidResponseDataException e) {
			throw new RuntimeException(e);
		} catch (ClientActionRequiredException e) {
			throw new RuntimeException(e);
		} catch (MissingCredentialException e) {
			throw new RuntimeException(e);
		} catch (OAuthException e) {
			throw new RuntimeException(e);
		} catch (InterruptedException e) {
			throw new RuntimeException(e);
		} catch (ParserConfigurationException e) {
			throw new RuntimeException(e);
		} catch (SAXException e) {
			throw new RuntimeException(e);
		}
	}
	
	public String completePayment(String token, double amount, String payerId){
		try {
			PayPalAPIInterfaceServiceService service = new PayPalAPIInterfaceServiceService(this
					.getClass().getResourceAsStream("/gr/handmademarket/resources/sdk_config.properties"));
			DoExpressCheckoutPaymentRequestType doCheckoutPaymentRequestType = new DoExpressCheckoutPaymentRequestType();
			DoExpressCheckoutPaymentRequestDetailsType details = new DoExpressCheckoutPaymentRequestDetailsType();
			details.setToken(token);
			details.setPayerID(payerId);
			BasicAmountType amountType = createAmountType(amount);
			details.setPaymentDetails(getPaymentDetails(amountType));
			doCheckoutPaymentRequestType.setDoExpressCheckoutPaymentRequestDetails(details);
			DoExpressCheckoutPaymentReq doExpressCheckoutPaymentReq = new DoExpressCheckoutPaymentReq();
			doExpressCheckoutPaymentReq.setDoExpressCheckoutPaymentRequest(doCheckoutPaymentRequestType);
			DoExpressCheckoutPaymentResponseType doCheckoutPaymentResponseType = service.doExpressCheckoutPayment(doExpressCheckoutPaymentReq);
			if (doCheckoutPaymentResponseType != null){
				for (ErrorType error : doCheckoutPaymentResponseType.getErrors()){
					System.out.println("error id: " + error.getErrorCode() + " message: " + error.getLongMessage());
				}
				return doCheckoutPaymentResponseType.getDoExpressCheckoutPaymentResponseDetails().getBillingAgreementID();
			}else{
				return null;
			}
		} catch (IOException e) {
			throw new RuntimeException(e);
		} catch (SSLConfigurationException e) {
			throw new RuntimeException(e);
		} catch (InvalidCredentialException e) {
			throw new RuntimeException(e);
		} catch (HttpErrorException e) {
			throw new RuntimeException(e);
		} catch (InvalidResponseDataException e) {
			throw new RuntimeException(e);
		} catch (ClientActionRequiredException e) {
			throw new RuntimeException(e);
		} catch (MissingCredentialException e) {
			throw new RuntimeException(e);
		} catch (OAuthException e) {
			throw new RuntimeException(e);
		} catch (InterruptedException e) {
			throw new RuntimeException(e);
		} catch (ParserConfigurationException e) {
			throw new RuntimeException(e);
		} catch (SAXException e) {
			throw new RuntimeException(e);
		}
	}
}
